#include<stdio.h>
#include<gmp.h>
#include<time.h>

#define PRECISAO 33219280 //Precisão utilizada para o calculo de pi

int main(void){
    	int i;
    	mpf_t a0, a1, b0, b1, t0, t1, p0, p1, pi, pi_aux, pi_old;
	time_t start, end;

	time(&start); //Inicio da contagem do tempo de execucao do calculo

	mpf_set_default_prec(PRECISAO);

	//Inicialização das variáveis
	mpf_init(a0);
	mpf_init(a1);
	mpf_init(b0);
	mpf_init(b1);
	mpf_init(t0);
	mpf_init(t1);
	mpf_init(p0);
	mpf_init(p1);
	mpf_init(pi);
	mpf_init(pi_aux);
	mpf_init(pi_old);

	//Pi "old" é 0, pi é 1 para que a comparação seja diferente na primeira vez
	mpf_set_d(pi_old,0);
	mpf_set_d(pi,1);

	mpf_set_d(a0,1);//a0 = 1.0

	mpf_set_d(b0,2);//b0 = 1.0/sqrt(2);
	mpf_sqrt(b0,b0);
	mpf_ui_div(b0,1,b0);

    mpf_set_d(t0,1);//t0 = 1.0/4;
	mpf_div_ui(t0,t0,4);

    	mpf_set_d(p0,1);//p0 = 1.0;

    	while(mpf_cmp(pi_old,pi) != 0){
		mpf_set(pi_old,pi);//pi_old agora é igual ao pi da iteração anterior

       	mpf_add(a1,a0,b0);//a1 = (a0+b0)/2;
		mpf_div_ui(a1,a1,2);

       	mpf_mul(b1,a0,b0);//b1 = sqrt(a0*b0);
		mpf_sqrt(b1,b1);

       	mpf_sub(t1,a0,a1);//t1 = t0 - (p0*pow((a0-a1),2));
		mpf_pow_ui(t1,t1,2);
		mpf_mul(t1,p0,t1);
		mpf_sub(t1,t0,t1);

       	mpf_mul_ui(p1,p0,2);//p1 = 2*p0;

       	mpf_add(pi,a1,b1);//pi = pow((a1+b1),2)/(4*t1);
		mpf_pow_ui(pi,pi,2);
		mpf_mul_ui(pi_aux,t1,4);
		mpf_div(pi,pi,pi_aux);

       	gmp_printf("%da interacao: pi %.Ff\n\n",i+1, pi);//imprime qual o valor de pi na iteração i

		i++;
       	mpf_set(a0,a1);//a0 = a1;
       	mpf_set(b0,b1);//b0 = b1;
       	mpf_set(t0,t1);//t0 = t1;
       	mpf_set(p0,p1);//p0 = p1;

   	}

	time(&end); //Inicio da contagem do tempo de execucao do calculo
	printf("Numero de iterações necessárias: %d\n", i);
	printf("Tempo total: %lf segundos\n\n", difftime(end,start));

	mpf_clear(a0);
	mpf_clear(a1);
	mpf_clear(b0);
	mpf_clear(b1);
	mpf_clear(t0);
	mpf_clear(t1);
	mpf_clear(p0);
	mpf_clear(p1);
	mpf_clear(pi);
	mpf_clear(pi_aux);
	mpf_clear(pi_old);

   	return 0;
}
